fn metadata_no_deps(ws: &Workspace,
_opt: &OutputMetadataOptions) -> CargoResult<ExportInfo> {
Ok(ExportInfo {
- packages: vec![try!(ws.current()).clone()],
+ packages: ws.members().cloned().collect(),
+ workspace_members: ws.members().map(|pkg| pkg.package_id().clone()).collect(),
resolve: None,
version: VERSION,
})
Ok(ExportInfo {
packages: packages,
- resolve: Some(MetadataResolve(resolve, try!(ws.current()).package_id().clone())),
+ workspace_members: ws.members().map(|pkg| pkg.package_id().clone()).collect(),
+ resolve: Some(MetadataResolve{
+ resolve: resolve,
+ root: ws.current_opt().map(|pkg| pkg.package_id().clone()),
+ }),
version: VERSION,
})
}
#[derive(RustcEncodable)]
pub struct ExportInfo {
packages: Vec<Package>,
+ workspace_members: Vec<PackageId>,
resolve: Option<MetadataResolve>,
version: u32,
}
/// Newtype wrapper to provide a custom `Encodable` implementation.
/// The one from lockfile does not fit because it uses a non-standard
/// format for `PackageId`s
-struct MetadataResolve(Resolve, PackageId);
+struct MetadataResolve{
+ resolve: Resolve,
+ root: Option<PackageId>,
+}
impl Encodable for MetadataResolve {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
#[derive(RustcEncodable)]
struct EncodableResolve<'a> {
- root: &'a PackageId,
+ root: Option<&'a PackageId>,
nodes: Vec<Node<'a>>,
}
dependencies: Vec<&'a PackageId>,
}
- let resolve = &self.0;
- let root = &self.1;
let encodable = EncodableResolve {
- root: root,
- nodes: resolve.iter().map(|id| {
+ root: self.root.as_ref(),
+ nodes: self.resolve.iter().map(|id| {
Node {
id: id,
- dependencies: resolve.deps(id).collect(),
+ dependencies: self.resolve.deps(id).collect(),
}
}).collect(),
};
.clone()]));
// If we're resolving everything then we include all members of the
- // workspace. If we want a specific set of requirements then we only
- // resolve the main crate as it's the only one we're compiling. This
+ // workspace. If we want a specific set of requirements and we're
+ // compiling only a single workspace crate then resolve only it. This
// case should only happen after we have a previous resolution, however,
// so assert that the previous exists.
- let method = match method {
- Method::Everything => Method::Everything,
- Method::Required { .. } => {
- assert!(previous.is_some());
- if member.package_id() == try!(ws.current()).package_id() {
- method
- } else {
- continue
+ if let Method::Required { .. } = method {
+ assert!(previous.is_some());
+ if let Some(current) = ws.current_opt() {
+ if member.package_id() != current.package_id() {
+ continue;
}
}
- };
+ }
// If we don't have a previous instance of resolve then we just need to
// resolve our entire summary (method should be Everything) and we just
use hamcrest::assert_that;
use cargotest::support::registry::Package;
-use cargotest::support::{project, execs, basic_bin_manifest, main_file};
+use cargotest::support::{project, execs, basic_bin_manifest, basic_lib_manifest, main_file};
#[test]
fn cargo_metadata_simple() {
"manifest_path": "[..]Cargo.toml"
}
],
+ "workspace_members": ["foo 0.5.0 (path+file:[..]foo)"],
"resolve": {
"nodes": [
{
"version": "0.5.0"
}
],
+ "workspace_members": ["foo 0.5.0 (path+file:[..]foo)"],
"resolve": {
"nodes": [
{
}"#));
}
+#[test]
+fn workspace_metadata() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [workspace]
+ members = ["bar", "baz"]
+ "#)
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
+ .file("bar/src/lib.rs", "")
+ .file("baz/Cargo.toml", &basic_lib_manifest("baz"))
+ .file("baz/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo_process("metadata"), execs().with_status(0).with_json(r#"
+ {
+ "packages": [
+ {
+ "name": "bar",
+ "version": "0.5.0",
+ "id": "bar[..]",
+ "source": null,
+ "dependencies": [],
+ "targets": [
+ {
+ "kind": [ "lib" ],
+ "name": "bar",
+ "src_path": "[..]bar[..]src[..]lib.rs"
+ }
+ ],
+ "features": {},
+ "manifest_path": "[..]bar[..]Cargo.toml"
+ },
+ {
+ "name": "baz",
+ "version": "0.5.0",
+ "id": "baz[..]",
+ "source": null,
+ "dependencies": [],
+ "targets": [
+ {
+ "kind": [ "lib" ],
+ "name": "baz",
+ "src_path": "[..]baz[..]src[..]lib.rs"
+ }
+ ],
+ "features": {},
+ "manifest_path": "[..]baz[..]Cargo.toml"
+ }
+ ],
+ "workspace_members": ["baz 0.5.0 (path+file:[..]baz)", "bar 0.5.0 (path+file:[..]bar)"],
+ "resolve": {
+ "nodes": [
+ {
+ "dependencies": [],
+ "id": "baz 0.5.0 (path+file:[..]baz)"
+ },
+ {
+ "dependencies": [],
+ "id": "bar 0.5.0 (path+file:[..]bar)"
+ }
+ ],
+ "root": null
+ },
+ "version": 1
+ }"#))
+}
+
+#[test]
+fn workspace_metadata_no_deps() {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [workspace]
+ members = ["bar", "baz"]
+ "#)
+ .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
+ .file("bar/src/lib.rs", "")
+ .file("baz/Cargo.toml", &basic_lib_manifest("baz"))
+ .file("baz/src/lib.rs", "");
+ p.build();
+
+ assert_that(p.cargo_process("metadata").arg("--no-deps"), execs().with_status(0).with_json(r#"
+ {
+ "packages": [
+ {
+ "name": "bar",
+ "version": "0.5.0",
+ "id": "bar[..]",
+ "source": null,
+ "dependencies": [],
+ "targets": [
+ {
+ "kind": [ "lib" ],
+ "name": "bar",
+ "src_path": "[..]bar[..]src[..]lib.rs"
+ }
+ ],
+ "features": {},
+ "manifest_path": "[..]bar[..]Cargo.toml"
+ },
+ {
+ "name": "baz",
+ "version": "0.5.0",
+ "id": "baz[..]",
+ "source": null,
+ "dependencies": [],
+ "targets": [
+ {
+ "kind": [ "lib" ],
+ "name": "baz",
+ "src_path": "[..]baz[..]src[..]lib.rs"
+ }
+ ],
+ "features": {},
+ "manifest_path": "[..]baz[..]Cargo.toml"
+ }
+ ],
+ "workspace_members": ["baz 0.5.0 (path+file:[..]baz)", "bar 0.5.0 (path+file:[..]bar)"],
+ "resolve": null,
+ "version": 1
+ }"#))
+}
+
#[test]
fn cargo_metadata_with_invalid_manifest() {
let p = project("foo")
"features":{},
"manifest_path":"[..]Cargo.toml"
}],
+ "workspace_members": [ "foo 0.5.0 (path+file:[..]foo)" ],
"resolve": null,
"version": 1
}"#;